/*SelectMode.java
 * 
 * Controls the select mode Activity
 * 
 * Shared Preferences code based on example from http://developer.android.com/guide/topics/data/data-storage.html
 * Alert dialog code based on an example from http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/AlertDialogSamples.html
 */
package com.tagit;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.SlidingDrawer;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.Toast;

public class SelectMode extends Activity {
	public static final String PREFS_NAME = "MyPrefsFile";// Store FTs booleans
															// and strings here

	private GridView gridview;
	private PhotoCursorAdapter mCursorAdapter;
	Button btReject;
	private PhotosDbAdapter mPhotoDb;
	SharedPreferences settings;
	int numAlgos;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		settings = getSharedPreferences(PREFS_NAME, 0); // Access FTs booleans
														// and strings

		mPhotoDb = new PhotosDbAdapter(this);
		mPhotoDb.open();
		mCursorAdapter = MyApp.getAdapter();
		setContentView(R.layout.selectmode);

		// Set up autocomplete in the tagging textbox
		List<String> listTags = mPhotoDb.getAllTags();
		String[] allTags = listTags.toArray(new String[] {});
		AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_tags);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				R.layout.list_tag, allTags);
		textView.setAdapter(adapter);

		// Create favorite tags buttons and set listeners
		Button FT1button = (Button) findViewById(R.id.FT1);
		setButtonText(FT1button, 1);
		setSetFTClickListener(FT1button, 1);

		Button FT2button = (Button) findViewById(R.id.FT2);
		setButtonText(FT2button, 2);
		setSetFTClickListener(FT2button, 2);

		Button FT3button = (Button) findViewById(R.id.FT3);
		setButtonText(FT3button, 3);
		setSetFTClickListener(FT3button, 3);

		Button FT4button = (Button) findViewById(R.id.FT4);
		setButtonText(FT4button, 4);
		setSetFTClickListener(FT4button, 4);

		Button FT5button = (Button) findViewById(R.id.FT5);
		setButtonText(FT5button, 5);
		setSetFTClickListener(FT5button, 5);

		Button FT6button = (Button) findViewById(R.id.FT6);
		setButtonText(FT6button, 6);
		setSetFTClickListener(FT6button, 6);

		Button tagMenuDoneButton = (Button) findViewById(R.id.tag_menu_done);
		setTagMenuDoneClickListener(tagMenuDoneButton);

		gridview = (GridView) findViewById(R.id.gridview2);
		mCursorAdapter.setState(1);
		gridview.setAdapter(mCursorAdapter);
		registerForContextMenu(gridview);

		setPicListener();

		setDoneClickListener();

		// Create the reject button and listener
		btReject = (Button) findViewById(R.id.reject);
		btReject.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (mCursorAdapter.getSelected().size() < 1) {
					Context context = getApplicationContext();
					CharSequence text = "Please select at least one picture before rejecting";
					int duration = Toast.LENGTH_LONG;
					Toast toast = Toast.makeText(context, text, duration);
					toast.show();
				} else {
					AlertDialog.Builder builder = createAlertDialog();
					AlertDialog alert = builder.create();
					alert.show();
				}

			}
		});

		// Set the listeners for the favorite tags buttons
		setSetFTClickListener();

		gridview.setAdapter(mCursorAdapter);

		// Currently no buttons set to recommended
		numAlgos = 0;

		// Set up the "Done" button and listener
		Button done = (Button) findViewById(R.id.newtag_done);
		done.setOnClickListener(new View.OnClickListener() {
			// @Override
			public void onClick(View v) {

				AutoCompleteTextView new_tag = (AutoCompleteTextView) findViewById(R.id.autocomplete_tags);
				if (new_tag.getText().length() == 0) {
					// This is kind of bad since it actually the user clicked
					// add without entering anything in the box
					return;
				}
				String tag = new_tag.getText().toString();
				for (long photo_id : mCursorAdapter.getSelected()) {
					mPhotoDb.addTagToPhoto(photo_id, tag);
				}
				new_tag.setText("");
				fillTagData();

			}
		});

		fillTagData();

	}

	// Method to set text on buttons when user comes back from configure menu
	@Override
	protected void onResume() {
		super.onResume();
		Button FT1button = (Button) findViewById(R.id.FT1);
		setButtonText(FT1button, 1);

		Button FT2button = (Button) findViewById(R.id.FT2);
		setButtonText(FT2button, 2);

		Button FT3button = (Button) findViewById(R.id.FT3);
		setButtonText(FT3button, 3);

		Button FT4button = (Button) findViewById(R.id.FT4);
		setButtonText(FT4button, 4);

		Button FT5button = (Button) findViewById(R.id.FT5);
		setButtonText(FT5button, 5);

		Button FT6button = (Button) findViewById(R.id.FT6);
		setButtonText(FT6button, 6);
	}

	// Listener for when a user clicks on a favorite tags button
	public void setSetFTClickListener(final Button b, final int num) {
		b.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {

				// Create keys for set preferences file
				String favKey = Integer.toString(num) + "F";
				String algoKey = Integer.toString(num) + "A";

				// Use keys to access booleans in set preference file
				boolean fav = settings.getBoolean(favKey, false); // True if FT
																	// is string
				boolean algo = settings.getBoolean(algoKey, false);// True if FT
																	// is
																	// recommended

				// If FT is set, add set value to photo, otherwise start
				// configuration menu Activity
				if (fav || algo) {
					String tag = getButtonText(b, num);
					for (long photo_id : mCursorAdapter.getSelected()) {
						mPhotoDb.addTagToPhoto(photo_id, tag);
					}
					fillTagData();

				} else {
					Intent intent = new Intent(v.getContext(),
							FavoriteTags.class);
					startActivity(intent);
				}
			}
		});
	}

	// Method to set text on buttons
	public void setButtonText(Button button, int num) {
		numAlgos = 0;
		button.setText(getButtonText(button, num));
	}

	// Method to return text associated with a given button
	public String getButtonText(Button button, int num) {
		String text = new String();

		// Create a key
		String favKey = Integer.toString(num) + "F";
		String algoKey = Integer.toString(num) + "A";
		String favString = Integer.toString(num) + "S";

		// Use keys to access booleans in set preference file
		boolean fav = settings.getBoolean(favKey, false);
		boolean algo = settings.getBoolean(algoKey, false);

		/*
		 * If set to string, return string, otherwise return the nth most recent
		 * tag on list of tags. If not enough tags have been set yet, return
		 * default tag "tree"
		 */
		if (fav) {
			text = settings.getString(favString, "?");
		} else if (algo) {
			PhotosDbAdapter mDb = new PhotosDbAdapter(this);
			mDb.open();
			final List<String> tags = mDb.getAllTags();

			int index = tags.size();
			if (index <= numAlgos) {
				text = "tree"; // If not enough tags yet, use "tree" as a
								// default (WIZARD OF OZ)
			} else {
				text = tags.get(numAlgos);
				numAlgos++;
			}
		} else {
			text = "?";
		}
		return text;
	}

	// Method to set the listener for each picture
	public void setPicListener() {
		gridview.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> parent, View v,
					int position, long id) {

				// If not selected, select; otherwise unselect
				if (!(mCursorAdapter.isSelected(mCursorAdapter
						.getItemId(position)))) {
					mCursorAdapter.addSelected(mCursorAdapter
							.getItemId(position));
					gridview.setAdapter(mCursorAdapter);
				} else {
					mCursorAdapter.removeSelected(mCursorAdapter
							.getItemId(position));
					gridview.setAdapter(mCursorAdapter);
				}

				// Then redraw
				fillTagData();
			}
		});
	}

	// Method for when a user clicks on Done button
	public void setDoneClickListener() {
		Button doneButton = (Button) findViewById(R.id.done);
		doneButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), PhotoGallery.class);
				startActivity(intent);
			}
		});
	}

	// Alert dialog to confirm that user wants to reject a photo
	private AlertDialog.Builder createAlertDialog() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage("Are you sure you want to reject this pictures?")
				.setCancelable(false)
				.setPositiveButton("Yes",
						new DialogInterface.OnClickListener() {
							int size = mCursorAdapter.getSelected().size();

							public void onClick(DialogInterface dialog, int id) {
								mPhotoDb.rejectMultiplePhotos(mCursorAdapter
										.getSelected());
								mCursorAdapter = new PhotoCursorAdapter(
										SelectMode.this, mPhotoDb
												.selectPhotos(20), 1);
								gridview.setAdapter(mCursorAdapter);

								fillTagData();

								// Toast message to let know the user he is on
								// select mode
								Context context = getApplicationContext();
								CharSequence text = "You just rejected " + size
										+ " pictures";
								int duration = Toast.LENGTH_LONG;
								Toast toast = Toast.makeText(context, text,
										duration);
								toast.show();
							}
						})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
					}
				});
		// AlertDialog alert = builder.create();
		return builder;
	}

	// Method for when a user clicks on the set favorite tags button
	public void setSetFTClickListener() {
		Button setFTButton = (Button) findViewById(R.id.setFT);
		setFTButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), FavoriteTags.class);
				startActivity(intent);
			}
		});
	}

	private void fillTagData() {
		GridView existing = (GridView) findViewById(R.id.gridview_existingtags);
		existing.setAdapter(new AnotherTagCursorAdapter(this));
	}

	private class AnotherTagCursorAdapter extends BaseAdapter {

		private Cursor mCursor;
		private Context mCtx;

		private AnotherTagCursorAdapter(Context ctx) {
			mCtx = ctx;
			mCursor = mPhotoDb.countTags(mCursorAdapter.getSelected());
		}

		// @Override
		public int getCount() {
			if (mCursor == null) {
				return 0;
			}
			int count = mCursor.getCount();
			return count;
		}

		// @Override
		public Object getItem(int position) {
			if (mCursor == null) {
				return null;
			}
			if (!mCursor.moveToPosition(position)) {
				return null;
			}
			String tag = mCursor.getString(mCursor
					.getColumnIndex(PhotosDbAdapter.KEY_TAG_CONTENT));
			long count = mCursor.getLong(mCursor.getColumnIndex("tag_count"));
			return tag + "[" + count + "] x";
		}

		// @Override
		public long getItemId(int position) {
			if (!mCursor.moveToPosition(position)) {
				return -1;
			}
			return mCursor.getLong(mCursor
					.getColumnIndex(PhotosDbAdapter.KEY_ID));
		}

		// @Override
		public View getView(int position, View convertView, ViewGroup parent) {
			Button b;

			if (convertView == null) {
				b = new Button(mCtx);
				b.setLayoutParams(new GridView.LayoutParams(
						GridView.LayoutParams.MATCH_PARENT,
						GridView.LayoutParams.MATCH_PARENT));
			} else {
				b = (Button) convertView;
			}
			b.setText((String) getItem(position));
			final long tag_id = getItemId(position);
			b.setOnClickListener(new View.OnClickListener() {
				final ArrayList<Long> photo_id = mCursorAdapter.getSelected();

				// @Override
				public void onClick(View v) {
					// for (long photo_id : mCursorAdapter.getSelected()) {
					AlertDialog.Builder builder = createAlertDialogBeforeDeleteTag(
							photo_id, tag_id);
					AlertDialog alert = builder.create();
					alert.show();
					// }
					// fillTagData();
				}
			});

			return b;
		}

	}

	private void CreateMenu(Menu menu) {
		menu.setQwertyMode(true);
		MenuItem mnu1 = menu.add(0, 0, 0, "Preferences");
		{
			mnu1.setAlphabeticShortcut('a');
		}
		MenuItem mnu2 = menu.add(0, 1, 1, "Help");
		{
			mnu2.setAlphabeticShortcut('b');
		}
	}

	private boolean MenuChoice(MenuItem item) {
		switch (item.getItemId()) {
		case 0:
			goToPreferences();
			return true;
		case 1:
			goToHelp();
			return true;
		}
		return false;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		CreateMenu(menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		return MenuChoice(item);
	}

	public void goToPreferences() {
		Intent intent = new Intent(SelectMode.this, Preferences.class);
		startActivity(intent);
	}

	public void goToHelp() {
		Intent intent = new Intent(SelectMode.this, Help.class);
		startActivity(intent);
	}

	// Listener for done button for tagging menu
	public void setTagMenuDoneClickListener(final Button b) {
		b.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				SlidingDrawer sd = (SlidingDrawer) findViewById(R.id.drawer);
				sd.close();
			}
		});
	}

	private AlertDialog.Builder createAlertDialogBeforeDeleteTag(
			final ArrayList<Long> photo_id, final long tag_id) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage("Are you sure you want to delete this tag?")
				.setCancelable(false)
				.setPositiveButton("Yes",
						new DialogInterface.OnClickListener() {
							// @Override
							public void onClick(DialogInterface dialog, int id) {
								for (long photo_id : mCursorAdapter
										.getSelected()) {
									mPhotoDb.removeTag(photo_id, tag_id);
								}
								// Toast message to let know the user deleted a
								// tag
								Context context = getApplicationContext();
								CharSequence text = "You just deleted a tag";
								int duration = Toast.LENGTH_LONG;
								Toast toast = Toast.makeText(context, text,
										duration);
								toast.show();
								fillTagData();
							}
						})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
					}
				});
		// AlertDialog alert = builder.create();
		return builder;
	}

}
